package czk.concrent.enjoyModelWithNotLock.atomicIntergerArray.practice;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @Author:ChenZhangKun
 * @Date: 2021/12/4 22:03
 */
public class AtomicIntegerArrayPra {
    public static void main(String[] args) throws InterruptedException {
        test(
                ()-> new AtomicIntegerArray(10),
                AtomicIntegerArray::length,
                AtomicIntegerArray::getAndIncrement,
                System.out::println);

        test(
                // 非原子性，有指令交错问题，线程不安全
                () -> new int[10],
                (array) -> array.length,
                (array, index) -> array[index]++,
                array -> System.out.println(Arrays.toString(array))
        );
    }

    public static <T> void test(Supplier<T> supplier,
                                Function<T, Integer> function,
                                BiConsumer<T, Integer> biConsumer,
                                Consumer<T> consumer) throws InterruptedException {
        // 拿到提供的数组
        T array = supplier.get();
        // 拿到数组长度
        Integer length = function.apply(array);
        List<Thread> list = new ArrayList<>();
        // 操作
        for (Integer i = 0; i < length; i++) {
            list.add(new Thread(() -> {
                for (int j = 0; j < 10 * 10000; j++) {
                    biConsumer.accept(array, j % length);
                }
            }));
        }
        for (Thread thread : list) {
            thread.start();
        }
        for (Thread thread : list) {
            thread.join();
        }
        consumer.accept(array);
    }
}
